import { inBrowser } from './env'
import {NoNumberCSSStyleDeclaration, offsetInfo, RectInfo} from "../types";

const elementStyle = inBrowser && document.createElement('div').style;

// type BrowserPrefix = 'transform' | 'webkitTransform' | 'MozTransform' | 'OTransform' | 'msTransform';
type BrowserPrefix = 'standard' | 'webkit' | 'Moz' | 'O' | 'ms';

const transforms = {
  standard: 'transform',
  webkit: 'webkitTransform',
  Moz: 'MozTransform',
  O: 'OTransform',
  ms: 'msTransform'
}

const vendor: boolean | BrowserPrefix = (() => {
  let result: boolean | BrowserPrefix = false;
  const transformNames: Array<BrowserPrefix> = ['standard', 'webkit', 'Moz', 'O', 'ms'];
  for (const value of transformNames) {
    // @ts-ignore
    if (elementStyle[transforms[value]]) {
      result = value;
      break;
    }
  }
  return result;
})();

function prefixStyle(style: NoNumberCSSStyleDeclaration | 'transitionEnd'): false | string {
  if (vendor === false) {
    return false
  }
  if (vendor === 'standard') {
    if (style === 'transitionEnd') {
      return 'transitionend';
    }
    return style
  }
  return vendor + style.charAt(0).toUpperCase() + style.substr(1)
}

const style = {
  transform: prefixStyle('transform'),
  transition: prefixStyle('transition'),
  transitionTimingFunction: prefixStyle('transitionTimingFunction'),
  transitionDuration: prefixStyle('transitionDuration'),
  transitionDelay: prefixStyle('transitionDelay'),
  transformOrigin: prefixStyle('transformOrigin'),
  transitionEnd: prefixStyle('transitionEnd')
}

function getRect(el: HTMLElement): RectInfo {
  if (el instanceof window.SVGElement) {
    let rect = el.getBoundingClientRect()
    return {
      top: rect.top,
      left: rect.left,
      width: rect.width,
      height: rect.height
    }
  } else {
    return {
      top: el.offsetTop,
      left: el.offsetLeft,
      width: el.offsetWidth,
      height: el.offsetHeight
    }
  }
}

// el 的offsetLeft和offsetTop
function offset(el: HTMLElement): offsetInfo {
  let left = 0
  let top = 0

  while (el) {
    left -= el.offsetLeft
    top -= el.offsetTop
    el = el.offsetParent as HTMLElement
  }

  return {
    left,
    top
  }
}


function checkPreventDefaultException(el: HTMLElement, exceptions: { [key: string]: RegExp }) {
  for (const key in exceptions) {
    // 匹配el.tagName  el.className等
    // @ts-ignore
    if (exceptions[key].test(el[key])) {
      return true
    }
  }
  return false
}


function tap(event: TouchEvent, eventName: string) {
  let ev = document.createEvent('Event');
  ev.initEvent(eventName, true, true);
  event.target!.dispatchEvent(ev);
}

export { style, getRect, offset, checkPreventDefaultException, tap };
